/*
 * UWT 2014
 */
package model;

import static com.google.common.base.Preconditions.*;

import java.awt.Color;
import java.awt.Dimension;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Jamada
 */
public class HeatMapData {
	private static final Logger logger = LoggerFactory.getLogger(HeatMapData.class);
	
    //Default heat map settings
    private static final String X_AXIS_LABEL = "Compound Name";
    private static final String Y_AXIS_LABEL = "Protein ID";
    private static final Color LOW_COLOR = Color.black;
    private static final Color HIGH_COLOR = Color.red;
    private static final Dimension CELL_SIZE = new Dimension(15, 10);
    
    //Core heat map attributes
    /**
     * Data for heat map.
     */
    private final double[][] data;
    /**
     * X-axis values of heat map.
     */
    private final Object[] xValues;
    /**
     * Y-axis values of heat map.
     */
    private final Object[] yValues;
    
    //Misc heat map settings
    /**
     * Title of heat map.
     */
    private String title;
    /**
     * Color of low data values.
     */
    private Color lowColor;
    /**
     * Color of high data values.
     */
    private Color highColor;
    /**
     * X-axis title label.
     */
    private String xAxisLabel;
    /**
     * Y-axis title label
     */
    private String yAxisLabel;
    /**
     * Size in pixels of each data cell.
     */
    private Dimension cellSize;
    /**
     * Whether X values appear horizontal or vertical.
     */
    private boolean xValuesHorizontal = false;
    
    
    public HeatMapData(final double[][] data, final Object[] xValues, final Object[] yValues) {
        this.data = checkNotNull(data);
        this.xValues = checkNotNull(xValues);
        this.yValues = checkNotNull(yValues);
        
        //default
        this.lowColor = LOW_COLOR;
        this.highColor = HIGH_COLOR;
        this.xAxisLabel = X_AXIS_LABEL;
        this.yAxisLabel = Y_AXIS_LABEL;
        setCellSize(CELL_SIZE);
    }
    
    public double getAvgSignal() {
    	int count = 0;
    	double sum = 0;
    	for (int i = 0; i < this.data.length; i++) {
    		for (int j = 0; j < this.xValues.length; j++) {
    			sum += this.data[i][j];
    			count ++;
    		}
    	}
    	return sum / count;
    }
    
    public void saveDataToFile(final String fileName) {
    	try {
    		final BufferedWriter bWriter = new BufferedWriter(new FileWriter(fileName));

    		logger.info("Writing heat map data to file {}", fileName);
    		final StringBuilder SB = new StringBuilder();
    		//Write column headings to output file
    		SB.append(Y_AXIS_LABEL);
    		for (int i = 0; i < this.xValues.length; i++) {
    			SB.append(", " + this.xValues[i]);
    		}
    		SB.append("\n");
    		bWriter.write(SB.toString());
    		SB.setLength(0); //clears StringBuilder

    		//Write data entries to file.
    		for (int i = 0; i < this.yValues.length; i ++) {
    			SB.append(this.yValues[i]);
    			for (int j = 0; j < this.xValues.length; j++) {
    				SB.append(", " + this.data[i][j]);
    			}
    			SB.append("\n");
    			bWriter.write(SB.toString());
    			SB.setLength(0);
    		}
    		bWriter.close();
    	} catch (IOException e) {
    		logger.error("IO error writing heat map data to file: {}", e);
    	}
    	
    }
    
    public void setCellSize(final Dimension cellSize) {
        this.cellSize = cellSize;
    }
    
    public void setLowColor(final Color lowColor) {
        this.lowColor = lowColor;
    }
    
    public void setHighColor(final Color highColor) {
        this.highColor = highColor;
    }
    
    public void setXAxisLabel(final String xAxisLabel) {
        this.xAxisLabel = xAxisLabel;
    }
    
    public void setYAxisLabel(final String yAxisLabel) {
        this.yAxisLabel = yAxisLabel;
    }
    
    public void setTitle(final String title) {
    	this.title = title;
    }
    
    public void setXValuesHorizontal(final boolean value) {
    	this.xValuesHorizontal = value;
    }
    
    public double[][] getData() {
        return this.data;
    }
    
    public Object[] getXValues() {
        return this.xValues;
    }
    
    public Object[] getYValues() {
        return this.yValues;
    }
    
    public Color getLowColor() {
        return this.lowColor;
    }
    
    public Color getHighColor() {
        return this.highColor;
    }
    
    public String getXAxisLabel() {
        return this.xAxisLabel;
    }
    
    public String getYAxisLabel() {
        return this.yAxisLabel;
    }
    
    public Dimension getCellSize() {
        return this.cellSize;
    }
    
    public String getTitle() {
    	return this.title;
    }
    
    public boolean getXValuesHorizontal() {
    	return this.xValuesHorizontal;
    }   
}
